/**
 * tieland.org
 * create on 2013-5-24
 */
package org.tieland.common.util;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

/**
 * 日期工具类
 * 
 * @author zhoux rainman.xiang@gmail.com
 */
public final class DateUtil {

	/** 一秒钟毫秒数 **/
	public static long ONE_SECOND_MILL_SECONDS = 1000;

	/** 一分钟毫秒数 **/
	public static long ONE_MINUTE_MILL_SECONDS = 60000;

	/** 一小时毫秒数 **/
	public static long AN_HOUR_MILL_SECONDS = 3600000;

	/** 一天毫秒数 **/
	public static long ONE_DAY_MILL_SECONDS = 86400000;

	/** 标准完整格式 **/
	public static final String SIMPLE_PATTERN = "yyyy-MM-dd HH:mm:ss";

	/** 年月日 **/
	public static final String YMD_PATTERN = "yyyy-MM-dd";

	/** 年月日（中文格式） **/
	public static final String YMD_CHN_PARTTERN = "yyyy年MM月dd日";

	/**
	 * 默认构造器
	 */
	private DateUtil() {
		super();
	}

	/**
	 * 获取date年份
	 * 
	 * @param date
	 * @return
	 */
	public static int getYear(Date date) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		return calendar.get(Calendar.YEAR);
	}

	/**
	 * 获取date月份，月份从0开始
	 * 
	 * @param date
	 * @return
	 */
	public static int getMonthDefault(Date date) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		return calendar.get(Calendar.MONTH);
	}

	/**
	 * 获取date月份，月份从1开始
	 * 
	 * @param date
	 * @return
	 */
	public static int getMonthReal(Date date) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		return calendar.get(Calendar.MONTH) + 1;
	}

	/**
	 * 获取date所在年份的第几周
	 * 
	 * @param date
	 * @return
	 */
	public static int getWeekOfYear(Date date) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		return calendar.get(Calendar.WEEK_OF_YEAR);
	}

	/**
	 * 获取date所在月份的第几周
	 * 
	 * @param date
	 * @return
	 */
	public static int getWeekOfMonth(Date date) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		return calendar.get(Calendar.WEEK_OF_MONTH);
	}

	/**
	 * 获取date所在年份第几天
	 * 
	 * @param date
	 * @return
	 */
	public static int getDayOfYear(Date date) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		return calendar.get(Calendar.DAY_OF_YEAR);
	}

	/**
	 * 获取date所在月份第几天
	 * 
	 * @param date
	 * @return
	 */
	public static int getDayOfMonth(Date date) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		return calendar.get(Calendar.DAY_OF_MONTH);
	}

	/**
	 * 获取date所在周第几天，从星期日开始
	 * 
	 * @param date
	 * @return
	 */
	public static int getDayOfWeekDefault(Date date) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		return calendar.get(Calendar.DAY_OF_WEEK);
	}

	/**
	 * 获取date所在周第一天，从星期日开始
	 * 
	 * @param date
	 * @return
	 */
	public static Date getFirstDateOfWeekDefault(Date date) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.set(Calendar.DAY_OF_WEEK,
				calendar.getActualMinimum(Calendar.DAY_OF_WEEK));
		calendar.set(Calendar.YEAR, getYear(date));
		calendar.set(Calendar.MONTH, getMonthDefault(date));
		calendar.set(Calendar.HOUR_OF_DAY, 0);
		calendar.set(Calendar.MINUTE, 0);
		calendar.set(Calendar.SECOND, 0);
		calendar.set(Calendar.MILLISECOND, 0);
		return calendar.getTime();
	}

	/**
	 * 获取date所在周第一天，从星期一开始
	 * 
	 * @param date
	 * @return
	 */
	public static Date getFirstDateOfWeekReal(Date date) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.setFirstDayOfWeek(Calendar.MONDAY);
		calendar.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
		calendar.set(Calendar.YEAR, getYear(date));
		calendar.set(Calendar.MONTH, getMonthDefault(date));
		calendar.set(Calendar.HOUR_OF_DAY, 0);
		calendar.set(Calendar.MINUTE, 0);
		calendar.set(Calendar.SECOND, 0);
		calendar.set(Calendar.MILLISECOND, 0);
		return calendar.getTime();
	}

	/**
	 * 获取date所在周最后一天，从星期日开始
	 * 
	 * @param date
	 * @return
	 */
	public static Date getEndDateOfWeekDefault(Date date) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.set(Calendar.DAY_OF_WEEK,
				calendar.getActualMaximum(Calendar.DAY_OF_WEEK));
		calendar.set(Calendar.YEAR, getYear(date));
		calendar.set(Calendar.MONTH, getMonthDefault(date));
		calendar.set(Calendar.HOUR_OF_DAY, 0);
		calendar.set(Calendar.MINUTE, 0);
		calendar.set(Calendar.SECOND, 0);
		calendar.set(Calendar.MILLISECOND, 0);
		return calendar.getTime();
	}

	/**
	 * 获取date所在周最后一天，从星期一开始
	 * 
	 * @param date
	 * @return
	 */
	public static Date getEndDateOfWeekReal(Date date) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.setFirstDayOfWeek(Calendar.MONDAY);
		calendar.set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY);
		calendar.set(Calendar.YEAR, getYear(date));
		calendar.set(Calendar.MONTH, getMonthDefault(date));
		calendar.set(Calendar.HOUR_OF_DAY, 0);
		calendar.set(Calendar.MINUTE, 0);
		calendar.set(Calendar.SECOND, 0);
		calendar.set(Calendar.MILLISECOND, 0);
		return calendar.getTime();
	}

	/**
	 * 获取date小时数
	 * 
	 * @param date
	 * @return
	 */
	public static int getHour(Date date) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		return calendar.get(Calendar.HOUR_OF_DAY);
	}

	/**
	 * 获取date分钟数
	 * 
	 * @param date
	 * @return
	 */
	public static int getMinute(Date date) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		return calendar.get(Calendar.MINUTE);
	}

	/**
	 * 获取date的秒数
	 * 
	 * @param date
	 * @return
	 */
	public static int getSecond(Date date) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		return calendar.get(Calendar.SECOND);
	}

	/**
	 * 获取date转化为毫秒数
	 * 
	 * @param date
	 * @return
	 */
	public static long getMilliSecond(Date date) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		return calendar.getTimeInMillis();
	}

	/**
	 * 获取当前日期所在年份的第一天 如：2011-09-08 返回值为 2011-01-01
	 * 
	 * @param date
	 * @return
	 */
	public static Date getFirstDateOfYear(Date date) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.set(Calendar.YEAR, getYear(date));
		calendar.set(Calendar.MONTH, 0);
		calendar.set(Calendar.DAY_OF_MONTH, 1);
		calendar.set(Calendar.HOUR_OF_DAY, 0);
		calendar.set(Calendar.MINUTE, 0);
		calendar.set(Calendar.SECOND, 0);
		calendar.set(Calendar.MILLISECOND, 0);
		return calendar.getTime();
	}

	/**
	 * 获取当前日期所在年份的最后一天 如：2011-09-08 返回值为 2011-12-31
	 * 
	 * @param date
	 * @return
	 */
	public static Date getEndDateOfYear(Date date) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.set(Calendar.YEAR, getYear(date));
		calendar.set(Calendar.MONTH, calendar.getActualMaximum(Calendar.MONTH));
		calendar.set(Calendar.DAY_OF_MONTH,
				calendar.getActualMaximum(Calendar.DAY_OF_MONTH));
		calendar.set(Calendar.HOUR_OF_DAY, 0);
		calendar.set(Calendar.MINUTE, 0);
		calendar.set(Calendar.SECOND, 0);
		calendar.set(Calendar.MILLISECOND, 0);
		return calendar.getTime();
	}

	/**
	 * 获取当前日期所在月的第一天 如：2011-09-08 返回值为 2011-09-01
	 * 
	 * @param date
	 * @return
	 */
	public static Date getFirstDateOfMonth(Date date) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.set(Calendar.YEAR, getYear(date));
		calendar.set(Calendar.MONTH, getMonthDefault(date));
		calendar.set(Calendar.DAY_OF_MONTH, 1);
		calendar.set(Calendar.HOUR_OF_DAY, 0);
		calendar.set(Calendar.MINUTE, 0);
		calendar.set(Calendar.SECOND, 0);
		calendar.set(Calendar.MILLISECOND, 0);
		return calendar.getTime();
	}

	/**
	 * 获取当前日期所在月的最后一天 如：2011-09-08 返回值为 2011-09-30
	 * 
	 * @param date
	 * @return
	 */
	public static Date getEndDateOfMonth(Date date) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.set(Calendar.MONTH, getMonthDefault(date));
		calendar.set(Calendar.DAY_OF_MONTH,
				calendar.getActualMaximum(Calendar.DAY_OF_MONTH));
		calendar.set(Calendar.HOUR_OF_DAY, 0);
		calendar.set(Calendar.MINUTE, 0);
		calendar.set(Calendar.SECOND, 0);
		calendar.set(Calendar.MILLISECOND, 0);
		return calendar.getTime();
	}
	
	/**
	 * 增加年份
	 * @param date
	 * @param addYear
	 * @return
	 */
	public static Date addYear(Date date, int year){
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.set(Calendar.YEAR, getYear(date)+year);
		return calendar.getTime();
	}
	
	/**
	 * 增加月份
	 * @param date
	 * @param month
	 * @return
	 */
	public static Date addMonth(Date date, int month){
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.set(Calendar.MONTH, getMonthDefault(date)+month);
		return calendar.getTime();
	}

	/**
	 * 获取前一天日期 如：2011-09-02返回值为2011-09-01
	 * 
	 * @param date
	 * @return
	 */
	public static Date getBeforeDate(Date date) {
		return addDate(date, -1);
	}

	/**
	 * 获取后一天日期 如：2011-09-02返回值为2011-09-03
	 * 
	 * @param date
	 * @return
	 */
	public static Date getNextDate(Date date) {
		return addDate(date, 1);
	}

	/**
	 * 获取date起始点 如：2011-09-01 12:12:30返回值为2011-09-01 00:00:00
	 * 
	 * @param date
	 * @return
	 */
	public static Date getDateOfBegin(Date date) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.set(Calendar.YEAR, getYear(date));
		calendar.set(Calendar.MONTH, getMonthDefault(date));
		calendar.set(Calendar.DAY_OF_MONTH, getDayOfMonth(date));
		calendar.set(Calendar.HOUR_OF_DAY, 0);
		calendar.set(Calendar.MINUTE, 0);
		calendar.set(Calendar.SECOND, 0);
		calendar.set(Calendar.MILLISECOND, 0);
		return calendar.getTime();
	}

	/**
	 * 获取date结束点 如：2011-09-01 12:12:30返回值为2011-09-01 00:00:00
	 * 
	 * @param date
	 * @return
	 */
	public static Date getDateOfEnd(Date date) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.set(Calendar.YEAR, getYear(date));
		calendar.set(Calendar.MONTH, getMonthDefault(date));
		calendar.set(Calendar.DAY_OF_MONTH, getDayOfMonth(date));
		calendar.set(Calendar.HOUR_OF_DAY, 23);
		calendar.set(Calendar.MINUTE, 59);
		calendar.set(Calendar.SECOND, 59);
		calendar.set(Calendar.MILLISECOND,
				calendar.getActualMaximum(Calendar.MILLISECOND));
		return calendar.getTime();
	}

	/**
	 * 日期偏移（增加或减少）
	 * 
	 * @param date
	 *            日期
	 * @param days
	 *            偏移量
	 * @return
	 */
	public static Date addDate(Date date, int days) {
		Calendar calendar = Calendar.getInstance();
		long millis = getMilliSecond(date) + days * ONE_DAY_MILL_SECONDS;
		calendar.setTimeInMillis(millis);
		return calendar.getTime();
	}

	/**
	 * 计算两个日期相隔天数,endDate-startDate
	 * 
	 * @param startDate
	 * @param endDate
	 * @return
	 */
	public static long diffDays(Date startDate, Date endDate) {
		return (getMilliSecond(endDate) - getMilliSecond(startDate))
				/ ONE_DAY_MILL_SECONDS;
	}

	/**
	 * 计算两个日期相隔秒数,endDate-startDate
	 * 
	 * @param startDate
	 * @param endDate
	 * @return
	 */
	public static long diffSeconds(Date startDate, Date endDate) {
		return (getMilliSecond(endDate) - getMilliSecond(startDate))
				/ ONE_SECOND_MILL_SECONDS;
	}

	/**
	 * 计算两个日期相隔毫秒数,endDate-startDate
	 * 
	 * @param startDate
	 * @param endDate
	 * @return
	 */
	public static long diffMilliSeconds(Date startDate, Date endDate) {
		return getMilliSecond(endDate) - getMilliSecond(startDate);
	}
	
	/**
	 * 日期格式 化
	 * @param date
	 * @param dateStyle
	 * @return
	 */
	public static String format(Date date, DateStyleEnum dateStyle){
		return format(date, dateStyle.getStyle());
	}

	/**
	 * 日期格式化
	 * 
	 * @param date
	 * @param format
	 * @return
	 */
	public static String format(Date date, String format) {
		if (date == null)
			return null;
		SimpleDateFormat dateFormat = new SimpleDateFormat(format);
		return dateFormat.format(date);
	}

	/**
	 * "yyyy-MM-dd HH:mm:ss"日期格式化
	 * 
	 * @param date
	 * @return
	 */
	public static String getSimpleDate(Date date) {
		return format(date, SIMPLE_PATTERN);
	}

	/**
	 * "yyyy-MM-dd"日期格式化
	 * 
	 * @param date
	 * @return
	 */
	public static String getYMDDate(Date date) {
		return format(date, YMD_PATTERN);
	}

	/**
	 * "yyyy年MM月dd日"日期格式化
	 * 
	 * @param date
	 * @return
	 */
	public static String getYMDCHNDate(Date date) {
		return format(date, YMD_CHN_PARTTERN);
	}

	/**
	 * 按格式解析日期
	 * 
	 * @param date
	 * @param format
	 * @return
	 * @throws ParseException
	 */
	public static Date parseDate(String date, String format)
			throws ParseException {
		if (date == null)
			return null;
		SimpleDateFormat dateFormat = new SimpleDateFormat(format);
		return dateFormat.parse(date);
	}
	
	/**
	 * 按格式解析日期
	 * @param date
	 * @param dateStyle
	 * @return
	 * @throws ParseException
	 */
	public static Date parseDate(String date, DateStyleEnum dateStyle) throws ParseException{
		return parseDate(date, dateStyle.getStyle());
	}

	/**
	 * "yyyy-MM-dd HH:mm:ss"格式解析日期
	 * 
	 * @param strDate
	 * @return
	 * @throws ParseException
	 */
	public static Date parseSimpleDate(String strDate) throws ParseException {
		return parseDate(strDate, SIMPLE_PATTERN);
	}

	/**
	 * "yyyy-MM-dd"格式解析日期
	 * 
	 * @param strDate
	 * @return
	 * @throws ParseException
	 */
	public static Date parseYMDDate(String strDate) throws ParseException {
		return parseDate(strDate, YMD_PATTERN);
	}

	/**
	 * "yyyy年MM月dd日"格式解析日期
	 * 
	 * @param strDate
	 * @return
	 * @throws ParseException
	 */
	public static Date parseYMDCHNDate(String strDate) throws ParseException {
		return parseDate(strDate, YMD_CHN_PARTTERN);
	}

	/**
	 * 判断日期有效期 如：checkDate=2013-09-02 startDate=2013-09-01 endDate=2013-09-03
	 * 返回true 如：checkDate=2013-09-04 startDate=2013-09-01 endDate=2013-09-03
	 * 返回false
	 * 
	 * @param startDate
	 * @param endDate
	 * @param checkDate
	 * @return
	 */
	public static boolean checkBetween(Date startDate, Date endDate,
			Date checkDate) {
		return (diffMilliSeconds(startDate, checkDate) >= 0 && diffMilliSeconds(
				checkDate, endDate) <= 0);
	}

	/**
	 * 判断是否闰年
	 * @param date
	 * @return
	 */
	public static boolean isLeapYear(Date date) {
		return isLeapYear(getYear(date));
	}

	/**
	 * 判断是否闰年
	 * @param year
	 * @return
	 */
	public static boolean isLeapYear(int year) {
		if ((year % 4 == 0 && year % 100 != 0) || (year % 400) == 0) {
			return true;
		} else {
			return false;
		}
	}
}
